import 'package:http_parser/http_parser.dart';

import '../common/test_page.dart';

class MediaTypeTestPage extends TestPage{
  MediaTypeTestPage(super.title) {
    group('parse', () {
      test('MediaType.parse("text/plain")', () {
        final type = MediaType.parse('text/plain');
        expect(type.type, ('text'));
        expect(type.subtype, ('plain'));
      });

      test('MediaType.parse("text/plain").mimeType 参数格式不同的情况', () {
        expect(MediaType.parse(' text/plain').mimeType, ('text/plain'));
        expect(MediaType.parse('\ttext/plain').mimeType, ('text/plain'));

        expect(MediaType.parse('text/plain ').mimeType, ('text/plain'));
        expect(MediaType.parse('text/plain\t').mimeType, ('text/plain'));

        expect(() => MediaType.parse('te(xt/plain'), '');
        expect(() => MediaType.parse('text/pla=in'), '');

        expect(() => MediaType.parse('text /plain'), '');
        expect(() => MediaType.parse('text/ plain'), '');
      });

      test('MediaType.parse("text/plain;foo=bar;baz=bang")', () {
        final type = MediaType.parse('text/plain;foo=bar;baz=bang');
        expect(type.mimeType, ('text/plain'));
        expect(type.parameters, ({'foo': 'bar', 'baz': 'bang'}));
      });

      test('MediaType.parse("text/plain ; foo=bar ; baz=bang")', () {
        final type = MediaType.parse('text/plain ; foo=bar ; baz=bang');
        expect(type.mimeType, ('text/plain'));
        expect(type.parameters, ({'foo': 'bar', 'baz': 'bang'}));
      });

      test('MediaType.parse("text/plain ; foo=bar ; baz=bang") 参数格式不同的情况', () {
        expect(
                () => MediaType.parse('text/plain; foo =bar'), '');
        expect(
                () => MediaType.parse('text/plain; foo= bar'), '');

        expect(
                () => MediaType.parse('text/plain; fo:o=bar'), '');
        expect(
                () => MediaType.parse('text/plain; foo=b@ar'), '');
      });

      test('MediaType.parse(r"text/plain; foo="bar space"; baz="bang\\escape"")', () {
        final type = MediaType.parse(r'text/plain; foo="bar space"; baz="bang\\escape"');
        expect(type.mimeType, ('text/plain'));
        expect(type.parameters, ({'foo': 'bar space', 'baz': r'bang\escape'}));
      });

      test('MediaType.parse("TeXt/pLaIn")', () {
        final type = MediaType.parse('TeXt/pLaIn');
        expect(type.type, ('text'));
        expect(type.subtype, ('plain'));
        expect(type.mimeType, ('text/plain'));
      });

      test('MediaType.parse("test/plain;FoO=bar;bAz=bang")', () {
        final type = MediaType.parse('test/plain;FoO=bar;bAz=bang');
        expect(type.parameters, ({'FoO': 'bar', 'bAz': 'bang'}));
        expect(type.parameters, ({'foo', 'bar'}));
        expect(type.parameters, ({'baz', 'bang'}));
      });
    });

    group('change', () {

      test('uMediaType.parse("text/plain; foo=bar; baz=bang").change()', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        final newType = type.change();
        expect(newType.type, ('text'));
        expect(newType.subtype, ('plain'));
        expect(newType.parameters, ({'foo': 'bar', 'baz': 'bang'}));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(type: "new").type', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(type.change(type: 'new').type, ('new'));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(subtype: "new").subtype', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(type.change(subtype: 'new').subtype, ('new'));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(mimeType: "image/png")', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        final newType = type.change(mimeType: 'image/png');
        expect(newType.type, ('image'));
        expect(newType.subtype, ('png'));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(parameters: {"foo": "zap", "qux": "fblthp"}).parameters', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(
            type.change(parameters: {'foo': 'zap', 'qux': 'fblthp'}).parameters,
            ({'foo': 'zap', 'baz': 'bang', 'qux': 'fblthp'}));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(clearParameters: true).parameters', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(type.change(clearParameters: true).parameters, 'isEmpty');
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(parameters: {"foo": "zap"}, clearParameters: true)', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        final newType = type.change(parameters: {'foo': 'zap'}, clearParameters: true);
        expect(newType.parameters, ({'foo': 'zap'}));
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(type: "new", mimeType: "image/png")', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(() => type.change(type: 'new', mimeType: 'image/png'),
            '');
      });

      test('MediaType.parse("text/plain; foo=bar; baz=bang").change(subtype: "new", mimeType: "image/png")', () {
        MediaType type = MediaType.parse('text/plain; foo=bar; baz=bang');
        expect(() => type.change(subtype: 'new', mimeType: 'image/png'),
            '');
      });
    });

    group('toString', () {
      test('MediaType("text", "plain").toString()', () {
        expect(MediaType('text', 'plain').toString(), 'text/plain');
      });

      test('MediaType("text", "plain", {"foo": "bar"}).toString()', () {
        expect(MediaType('text', 'plain', {'foo': 'bar'}).toString(), 'text/plain; foo=bar');
      });

      test('MediaType("text", "plain", {"foo": "bar baz"}).toString()', () {
        expect(MediaType('text', 'plain', {'foo': 'bar baz'}).toString(),
            'text/plain; foo="bar baz"');
      });

      test('MediaType("text", "plain", {"foo": "bar"\x7Fbaz"}).toString()', () {
        expect(MediaType('text', 'plain', {'foo': 'bar"\x7Fbaz'}).toString(),
            'text/plain; foo="bar\\"\\\x7Fbaz"');
      });

      test('MediaType("text", "plain", {"foo": "bar", "baz": "bang"}).toString()', () {
        expect(
            MediaType('text', 'plain', {'foo': 'bar', 'baz': 'bang'}).toString(),
            'text/plain; foo=bar; baz=bang');
      });
    });
  }

}